plotly入門#
この授業ではplotyを可視化ツールとして使います。
簡易版のplotly.expressについて簡単に概説します。
import pandas as pd
import plotly.express as px
tips = px.data.tips()
散布図#
散布図はpx.scatterで描けます。
書式は、データフレームとx軸、y軸を指定するのが基本です。
px.scatter(tips, x="total_bill", y="tip")
color=’size’などと指定すると客のサイズごとのデータ点を区別できます。
px.scatter(tips, x="total_bill", y="tip",color="size")
ファセットも簡単にできます。男女別にプロットを分けてみます。
px.scatter(tips, x="total_bill", y="tip",color="size", facet_col="sex")
折れ線グラフ#
px.lineを用います。
アジアに限定して折れ線グラフを書いてみます。
gapminder = px.data.gapminder()
gapminder_Asia = gapminder.query('continent=="Asia"')
gapminder_Asia.head()
| country | continent | year | lifeExp | pop | gdpPercap | iso_alpha | iso_num | |
|---|---|---|---|---|---|---|---|---|
| 0 | Afghanistan | Asia | 1952 | 28.801 | 8425333 | 779.445314 | AFG | 4 |
| 1 | Afghanistan | Asia | 1957 | 30.332 | 9240934 | 820.853030 | AFG | 4 |
| 2 | Afghanistan | Asia | 1962 | 31.997 | 10267083 | 853.100710 | AFG | 4 |
| 3 | Afghanistan | Asia | 1967 | 34.020 | 11537966 | 836.197138 | AFG | 4 |
| 4 | Afghanistan | Asia | 1972 | 36.088 | 13079460 | 739.981106 | AFG | 4 |
px.line(gapminder_Asia, x="year", y="gdpPercap", color="country")
Important
plotlyの最大の特徴はインタラクティブな操作ができることです。例えば、KuwaitのGDPが大きすぎるので、legendでKuwaitをクリックして、これを消すことができます。
棒グラフ#
棒グラフで日本と台湾のGDPの推移を見ます。
gapminder_Japan_Taiwan = gapminder.query('country=="Japan"|country=="Taiwan"')
gapminder_Japan_Taiwan
| country | continent | year | lifeExp | pop | gdpPercap | iso_alpha | iso_num | |
|---|---|---|---|---|---|---|---|---|
| 792 | Japan | Asia | 1952 | 63.030 | 86459025 | 3216.956347 | JPN | 392 |
| 793 | Japan | Asia | 1957 | 65.500 | 91563009 | 4317.694365 | JPN | 392 |
| 794 | Japan | Asia | 1962 | 68.730 | 95831757 | 6576.649461 | JPN | 392 |
| 795 | Japan | Asia | 1967 | 71.430 | 100825279 | 9847.788607 | JPN | 392 |
| 796 | Japan | Asia | 1972 | 73.420 | 107188273 | 14778.786360 | JPN | 392 |
| 797 | Japan | Asia | 1977 | 75.380 | 113872473 | 16610.377010 | JPN | 392 |
| 798 | Japan | Asia | 1982 | 77.110 | 118454974 | 19384.105710 | JPN | 392 |
| 799 | Japan | Asia | 1987 | 78.670 | 122091325 | 22375.941890 | JPN | 392 |
| 800 | Japan | Asia | 1992 | 79.360 | 124329269 | 26824.895110 | JPN | 392 |
| 801 | Japan | Asia | 1997 | 80.690 | 125956499 | 28816.584990 | JPN | 392 |
| 802 | Japan | Asia | 2002 | 82.000 | 127065841 | 28604.591900 | JPN | 392 |
| 803 | Japan | Asia | 2007 | 82.603 | 127467972 | 31656.068060 | JPN | 392 |
| 1500 | Taiwan | Asia | 1952 | 58.500 | 8550362 | 1206.947913 | TWN | 158 |
| 1501 | Taiwan | Asia | 1957 | 62.400 | 10164215 | 1507.861290 | TWN | 158 |
| 1502 | Taiwan | Asia | 1962 | 65.200 | 11918938 | 1822.879028 | TWN | 158 |
| 1503 | Taiwan | Asia | 1967 | 67.500 | 13648692 | 2643.858681 | TWN | 158 |
| 1504 | Taiwan | Asia | 1972 | 69.390 | 15226039 | 4062.523897 | TWN | 158 |
| 1505 | Taiwan | Asia | 1977 | 70.590 | 16785196 | 5596.519826 | TWN | 158 |
| 1506 | Taiwan | Asia | 1982 | 72.160 | 18501390 | 7426.354774 | TWN | 158 |
| 1507 | Taiwan | Asia | 1987 | 73.400 | 19757799 | 11054.561750 | TWN | 158 |
| 1508 | Taiwan | Asia | 1992 | 74.260 | 20686918 | 15215.657900 | TWN | 158 |
| 1509 | Taiwan | Asia | 1997 | 75.250 | 21628605 | 20206.820980 | TWN | 158 |
| 1510 | Taiwan | Asia | 2002 | 76.990 | 22454239 | 23235.423290 | TWN | 158 |
| 1511 | Taiwan | Asia | 2007 | 78.400 | 23174294 | 28718.276840 | TWN | 158 |
barmode=”group”とすると列でグループ化した棒グラフを描画できます。
px.bar(gapminder_Japan_Taiwan ,x="year", y="gdpPercap", color="country", barmode="group")
barmode=”overlay”とすると重なり合った棒グラフを描画できます。
px.bar(gapminder_Japan_Taiwan ,x="year", y="gdpPercap", color="country", barmode="overlay")
tidyデータ#
ハドリー・ウィッカムは、整然(tidy)データの条件として以下の4つを挙げています(https://ja.wikipedia.org/wiki/Tidy_data)。
個々の変数 (variable) が1つの列 (column) をなす。
個々の観測 (observation) が1つの行 (row) をなす。
個々の観測の構成単位の類型 (type of observational unit) が1つの表 (table) をなす。
個々の値 (value) が1つのセル (cell) をなす

応用ではデータをプロットするときにtidy形式にすると便利になります。
meltによる変換#
tidyデータを作るためにはどうすればよいでしょうか。
pandasではwideからlongへの変換に概ね相当します。
meltはデータフレームの横に並んでいる列変数を,一つの変数の値として縦に持つように変換します。
melt(id_vars = ‘year’, var_name = ‘var’, value_name = ‘value’)のように書く。
Important
変換しない変数はid.varとして指定する。
var_nameが元の列変数を値として持つ変換後の変数名
value_nameは元の値を縦に値として持つ変数名
tidy形式にすることで変数の値による曲線の使い分けなどができるようになります。
例えば、’lifeExp’,’gdpPercap’が同じグラフで比較したいとき。
このwideデータを変換して…
gapminder = px.data.gapminder()
gapminder_Japan = gapminder.query('country=="Japan"')[['year', 'lifeExp','gdpPercap']]
gapminder_Japan
| year | lifeExp | gdpPercap | |
|---|---|---|---|
| 792 | 1952 | 63.030 | 3216.956347 |
| 793 | 1957 | 65.500 | 4317.694365 |
| 794 | 1962 | 68.730 | 6576.649461 |
| 795 | 1967 | 71.430 | 9847.788607 |
| 796 | 1972 | 73.420 | 14778.786360 |
| 797 | 1977 | 75.380 | 16610.377010 |
| 798 | 1982 | 77.110 | 19384.105710 |
| 799 | 1987 | 78.670 | 22375.941890 |
| 800 | 1992 | 79.360 | 26824.895110 |
| 801 | 1997 | 80.690 | 28816.584990 |
| 802 | 2002 | 82.000 | 28604.591900 |
| 803 | 2007 | 82.603 | 31656.068060 |
longにします。
ここで’var’の値として、’lifeExp’,’gdpPercap’をもたせます。
gapminder_Japan_long = gapminder_Japan.melt(id_vars = 'year', var_name = 'var', value_name = 'value')
gapminder_Japan_long
| year | var | value | |
|---|---|---|---|
| 0 | 1952 | lifeExp | 63.030000 |
| 1 | 1957 | lifeExp | 65.500000 |
| 2 | 1962 | lifeExp | 68.730000 |
| 3 | 1967 | lifeExp | 71.430000 |
| 4 | 1972 | lifeExp | 73.420000 |
| 5 | 1977 | lifeExp | 75.380000 |
| 6 | 1982 | lifeExp | 77.110000 |
| 7 | 1987 | lifeExp | 78.670000 |
| 8 | 1992 | lifeExp | 79.360000 |
| 9 | 1997 | lifeExp | 80.690000 |
| 10 | 2002 | lifeExp | 82.000000 |
| 11 | 2007 | lifeExp | 82.603000 |
| 12 | 1952 | gdpPercap | 3216.956347 |
| 13 | 1957 | gdpPercap | 4317.694365 |
| 14 | 1962 | gdpPercap | 6576.649461 |
| 15 | 1967 | gdpPercap | 9847.788607 |
| 16 | 1972 | gdpPercap | 14778.786360 |
| 17 | 1977 | gdpPercap | 16610.377010 |
| 18 | 1982 | gdpPercap | 19384.105710 |
| 19 | 1987 | gdpPercap | 22375.941890 |
| 20 | 1992 | gdpPercap | 26824.895110 |
| 21 | 1997 | gdpPercap | 28816.584990 |
| 22 | 2002 | gdpPercap | 28604.591900 |
| 23 | 2007 | gdpPercap | 31656.068060 |
colorで’var’と指定すれば、’lifeExp’と’gdpPercap’を色分けできます。
px.line( gapminder_Japan_long, x='year',y='value', color='var')#よいプロットではない
goオブジェクト#
より高度な作図はgoオブジェクトを使います。
ここでは一枚のプロットに異なるY軸目盛りを表示する方法を紹介する。
go.Figure()でプロットの「白紙」を作る。
add_trace()で一つずつ散布図を重ねていく。
2つ目のY軸のデータには、yaxis=”y2”を指定して、2つ目のY軸に関連付ける。
update_layout()で二つのY軸の設定をする。
fig.show()で表示する。
import plotly.graph_objs as go
# プロットの作成
fig = go.Figure()
# Y1軸のデータ
fig.add_trace(go.Scatter(x=gapminder_Japan['year'], y=gapminder_Japan['lifeExp'], name="lifeExp", mode="lines+markers"))
# Y2軸のデータ
fig.add_trace(go.Scatter(x=gapminder_Japan['year'], y=gapminder_Japan['gdpPercap'], name="gdpPercap", mode="lines+markers", yaxis="y2"))
# Y軸の設定
fig.update_layout(
yaxis=dict(
title="'lifeExp",
titlefont=dict(color="blue"),
tickfont=dict(color="blue"),
),
yaxis2=dict(
title="gdpPercap",
titlefont=dict(color="red"),
tickfont=dict(color="red"),
anchor="x",
overlaying="y",
side="right",
),
)
fig.show()
Tip
pxのfacet_colなら異なるY軸を表示できるが煩雑になる。
fig = px.line( gapminder_Japan_long, x='year',y='value', facet_col='var')
# 各サブプロットのY軸の範囲を設定
fig.update_yaxes(matches=None)
def update_yaxis_range(axis, index):
if index == 0:
axis.update(range=[min(gapminder_Japan['lifeExp']) - 5, max(gapminder_Japan['lifeExp']) + 5])
else:
axis.update(range=[min(gapminder_Japan['gdpPercap']) - 500, max(gapminder_Japan['gdpPercap']) + 500] )
for index, axis in enumerate(fig.select_yaxes()):
update_yaxis_range(axis, index)
fig.show()
世界銀行の出生率データ#
生データの処理の実例を見てみます。 https://data.worldbank.org/indicator/SP.DYN.TFRT.IN
世界銀行の出生率データを可視化してみます。
生データの処理はいろいろ面倒です。
Caution
- csvの値の中に’,’が入っているのでpandasでは読み込めない。csvモジュールを使う。
import urllib.request
url = "https://raw.githubusercontent.com/berutaki/github.io/main/fertility_rate.csv"
import csv
from io import StringIO
# CSVファイルを正しく区切る
with urllib.request.urlopen(url) as f:
data = f.read().decode('utf-8')
data = StringIO(data)
reader = csv.reader(data, delimiter=',', quotechar='"')
data = [row for row in reader]
# データフレームに変換する
df = pd.DataFrame(data[5:], columns=data[4])#最初の4行は捨てる
年が横に入っているので、longに変換したい。
df.head()
| Country Name | Country Code | Indicator Name | Indicator Code | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | ... | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Aruba | ABW | Fertility rate, total (births per woman) | SP.DYN.TFRT.IN | 4.82 | 4.655 | 4.471 | 4.271 | 4.059 | 3.842 | ... | 2.117 | 2.148 | 1.972 | 1.953 | 1.839 | 1.587 | 1.486 | 1.325 | ||
| 1 | Africa Eastern and Southern | AFE | Fertility rate, total (births per woman) | SP.DYN.TFRT.IN | 6.72412501084242 | 6.74275210020318 | 6.76293005566599 | 6.77871194340642 | 6.78842004142392 | 6.80032228007056 | ... | 4.80882146896218 | 4.7398628747128 | 4.67761935515813 | 4.61567138298739 | 4.57041032724911 | 4.52770656918433 | 4.48289939808498 | 4.41690156838726 | ||
| 2 | Afghanistan | AFG | Fertility rate, total (births per woman) | SP.DYN.TFRT.IN | 7.282 | 7.284 | 7.292 | 7.302 | 7.304 | 7.305 | ... | 5.696 | 5.56 | 5.405 | 5.262 | 5.129 | 5.002 | 4.87 | 4.75 | ||
| 3 | Africa Western and Central | AFW | Fertility rate, total (births per woman) | SP.DYN.TFRT.IN | 6.45844789624312 | 6.47151755185967 | 6.49182578734167 | 6.50608758636194 | 6.52535544956749 | 6.54110170802647 | ... | 5.50634979270689 | 5.43749340764512 | 5.38505930791309 | 5.32870923111315 | 5.2553453710546 | 5.18631941888717 | 5.11893203861357 | 5.0493293781153 | ||
| 4 | Angola | AGO | Fertility rate, total (births per woman) | SP.DYN.TFRT.IN | 6.708 | 6.79 | 6.872 | 6.954 | 7.036 | 7.116 | ... | 5.953 | 5.864 | 5.774 | 5.686 | 5.6 | 5.519 | 5.442 | 5.371 |
5 rows × 67 columns
Caution
“Country Name”変数名にスペースが入っている
df["Country Name"].unique()
Show code cell output
array(['Aruba', 'Africa Eastern and Southern', 'Afghanistan',
'Africa Western and Central', 'Angola', 'Albania', 'Andorra',
'Arab World', 'United Arab Emirates', 'Argentina', 'Armenia',
'American Samoa', 'Antigua and Barbuda', 'Australia', 'Austria',
'Azerbaijan', 'Burundi', 'Belgium', 'Benin', 'Burkina Faso',
'Bangladesh', 'Bulgaria', 'Bahrain', 'Bahamas, The',
'Bosnia and Herzegovina', 'Belarus', 'Belize', 'Bermuda',
'Bolivia', 'Brazil', 'Barbados', 'Brunei Darussalam', 'Bhutan',
'Botswana', 'Central African Republic', 'Canada',
'Central Europe and the Baltics', 'Switzerland', 'Channel Islands',
'Chile', 'China', "Cote d'Ivoire", 'Cameroon', 'Congo, Dem. Rep.',
'Congo, Rep.', 'Colombia', 'Comoros', 'Cabo Verde', 'Costa Rica',
'Caribbean small states', 'Cuba', 'Curacao', 'Cayman Islands',
'Cyprus', 'Czechia', 'Germany', 'Djibouti', 'Dominica', 'Denmark',
'Dominican Republic', 'Algeria',
'East Asia & Pacific (excluding high income)',
'Early-demographic dividend', 'East Asia & Pacific',
'Europe & Central Asia (excluding high income)',
'Europe & Central Asia', 'Ecuador', 'Egypt, Arab Rep.',
'Euro area', 'Eritrea', 'Spain', 'Estonia', 'Ethiopia',
'European Union', 'Fragile and conflict affected situations',
'Finland', 'Fiji', 'France', 'Faroe Islands',
'Micronesia, Fed. Sts.', 'Gabon', 'United Kingdom', 'Georgia',
'Ghana', 'Gibraltar', 'Guinea', 'Gambia, The', 'Guinea-Bissau',
'Equatorial Guinea', 'Greece', 'Grenada', 'Greenland', 'Guatemala',
'Guam', 'Guyana', 'High income', 'Hong Kong SAR, China',
'Honduras', 'Heavily indebted poor countries (HIPC)', 'Croatia',
'Haiti', 'Hungary', 'IBRD only', 'IDA & IBRD total', 'IDA total',
'IDA blend', 'Indonesia', 'IDA only', 'Isle of Man', 'India',
'Not classified', 'Ireland', 'Iran, Islamic Rep.', 'Iraq',
'Iceland', 'Israel', 'Italy', 'Jamaica', 'Jordan', 'Japan',
'Kazakhstan', 'Kenya', 'Kyrgyz Republic', 'Cambodia', 'Kiribati',
'St. Kitts and Nevis', 'Korea, Rep.', 'Kuwait',
'Latin America & Caribbean (excluding high income)', 'Lao PDR',
'Lebanon', 'Liberia', 'Libya', 'St. Lucia',
'Latin America & Caribbean',
'Least developed countries: UN classification', 'Low income',
'Liechtenstein', 'Sri Lanka', 'Lower middle income',
'Low & middle income', 'Lesotho', 'Late-demographic dividend',
'Lithuania', 'Luxembourg', 'Latvia', 'Macao SAR, China',
'St. Martin (French part)', 'Morocco', 'Monaco', 'Moldova',
'Madagascar', 'Maldives', 'Middle East & North Africa', 'Mexico',
'Marshall Islands', 'Middle income', 'North Macedonia', 'Mali',
'Malta', 'Myanmar',
'Middle East & North Africa (excluding high income)', 'Montenegro',
'Mongolia', 'Northern Mariana Islands', 'Mozambique', 'Mauritania',
'Mauritius', 'Malawi', 'Malaysia', 'North America', 'Namibia',
'New Caledonia', 'Niger', 'Nigeria', 'Nicaragua', 'Netherlands',
'Norway', 'Nepal', 'Nauru', 'New Zealand', 'OECD members', 'Oman',
'Other small states', 'Pakistan', 'Panama', 'Peru', 'Philippines',
'Palau', 'Papua New Guinea', 'Poland', 'Pre-demographic dividend',
'Puerto Rico', "Korea, Dem. People's Rep.", 'Portugal', 'Paraguay',
'West Bank and Gaza', 'Pacific island small states',
'Post-demographic dividend', 'French Polynesia', 'Qatar',
'Romania', 'Russian Federation', 'Rwanda', 'South Asia',
'Saudi Arabia', 'Sudan', 'Senegal', 'Singapore', 'Solomon Islands',
'Sierra Leone', 'El Salvador', 'San Marino', 'Somalia', 'Serbia',
'Sub-Saharan Africa (excluding high income)', 'South Sudan',
'Sub-Saharan Africa', 'Small states', 'Sao Tome and Principe',
'Suriname', 'Slovak Republic', 'Slovenia', 'Sweden', 'Eswatini',
'Sint Maarten (Dutch part)', 'Seychelles', 'Syrian Arab Republic',
'Turks and Caicos Islands', 'Chad',
'East Asia & Pacific (IDA & IBRD countries)',
'Europe & Central Asia (IDA & IBRD countries)', 'Togo', 'Thailand',
'Tajikistan', 'Turkmenistan',
'Latin America & the Caribbean (IDA & IBRD countries)',
'Timor-Leste', 'Middle East & North Africa (IDA & IBRD countries)',
'Tonga', 'South Asia (IDA & IBRD)',
'Sub-Saharan Africa (IDA & IBRD countries)', 'Trinidad and Tobago',
'Tunisia', 'Turkiye', 'Tuvalu', 'Tanzania', 'Uganda', 'Ukraine',
'Upper middle income', 'Uruguay', 'United States', 'Uzbekistan',
'St. Vincent and the Grenadines', 'Venezuela, RB',
'British Virgin Islands', 'Virgin Islands (U.S.)', 'Vietnam',
'Vanuatu', 'World', 'Samoa', 'Kosovo', 'Yemen, Rep.',
'South Africa', 'Zambia', 'Zimbabwe'], dtype=object)
meltするために不要な列はdrop()で捨てる。
df = df.drop (columns = ["Country Code","Indicator Name","Indicator Code"] )
id_varsを”Country Name”、 var_nameを’year’, value_nameを’fertility_rate’としてmeltする。
melted_df = df.melt(id_vars="Country Name", var_name='year', value_name='fertility_rate')
‘ ‘を欠損値に変換
import numpy as np
melted_df.replace('', np.nan, inplace=True)
型変換
melted_df['fertility_rate'] = melted_df['fertility_rate'].astype(float)
やっとプロットできるが国が多すぎる。
px.line(melted_df, x = "year", y = "fertility_rate", color = "Country Name",markers=True)
国を選んで可視化
selected_countries = ['Japan','Korea, Rep.','China','Singapore']
px.line(melted_df[melted_df["Country Name"].isin(selected_countries)], x = "year", y = "fertility_rate", color = "Country Name",markers=True)#isinはグループへの包含を判定するpandasのメソッド
Chetty(2022)のデータ#
https://opportunityinsights.org/data/
import pandas as pd
url = "https://raw.githubusercontent.com/berutaki/github.io/main/social_capital_county.csv"
df = pd.read_csv(url)
df.head()
| county | county_name | num_below_p50 | pop2018 | ec_county | ec_se_county | child_ec_county | child_ec_se_county | ec_grp_mem_county | ec_high_county | ... | child_exposure_county | child_high_exposure_county | bias_grp_mem_county | bias_grp_mem_high_county | child_bias_county | child_high_bias_county | clustering_county | support_ratio_county | volunteering_rate_county | civic_organizations_county | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1001 | Autauga, Alabama | 5922.3921 | 55200.0 | 0.72077 | 0.00831 | 1.11754 | 0.02467 | 0.77223 | 1.21372 | ... | 1.14816 | 1.19944 | 0.05526 | -0.22748 | 0.02668 | -0.08229 | 0.10347 | 0.98275 | 0.04355 | 0.01518 |
| 1 | 1003 | Baldwin, Alabama | 15458.3960 | 208107.0 | 0.74313 | 0.00661 | 0.83064 | 0.01629 | 0.76215 | 1.28302 | ... | 0.84588 | 1.00797 | 0.02950 | -0.21519 | 0.01802 | -0.05241 | 0.09624 | 0.98684 | 0.06117 | 0.01526 |
| 2 | 1005 | Barbour, Alabama | 4863.9736 | 25782.0 | 0.41366 | 0.00978 | 0.58541 | 0.02707 | 0.35927 | 0.91897 | ... | 0.63306 | 0.71967 | 0.13457 | -0.34086 | 0.07528 | -0.19714 | 0.14911 | 0.99911 | 0.02093 | 0.01474 |
| 3 | 1007 | Bibb, Alabama | 3061.4934 | 22527.0 | 0.63152 | 0.01175 | 0.72265 | 0.03027 | 0.68094 | 1.06378 | ... | 0.71433 | 0.72395 | 0.04108 | -0.27727 | -0.01165 | -0.15993 | 0.14252 | 0.99716 | 0.05294 | 0.01439 |
| 4 | 1009 | Blount, Alabama | 6740.9116 | 57645.0 | 0.72562 | 0.00985 | 0.76096 | 0.02466 | 0.79584 | 1.10569 | ... | 0.74821 | 0.79375 | 0.00217 | -0.24946 | -0.01704 | -0.08745 | 0.11243 | 0.99069 | 0.05704 | 0.01724 |
5 rows × 26 columns
3つの社会関係資本(ec_county, clustering_county, volunteering_rate_county)と貧困率との関係を散布図で示す。
df['child_pov'] = df['num_below_p50']/df['pop2018']#中央値以下の貧困者の率
px.scatter(df, x = "ec_county", y = "child_pov")#ec_countyは経済的な社会資本の指標
px.scatter(df, x = "clustering_county", y = "child_pov")#clustering_countyは地域社会の結束力の指標
px.scatter(df, x = "volunteering_rate_county", y = "child_pov")#volunteering_rate_countyはボランティア率
df ['state'] = df['county_name'].str.split(',').apply(lambda x:x[1])#splitで,の前後[0 1]に分けた後、lambda関数で後ろ[1]だけとる。
州ごとに表示する。
px.scatter(df, x = "ec_county", y = "child_pov", facet_col = 'state', facet_col_wrap = 10)
東京都の婚姻・離婚件数の時系列推移#
df = pd.read_csv("https://www.hokeniryo.metro.tokyo.lg.jp/kiban/chosa_tokei/jinkodotaitokei/kushityosonbetsu.files/04koninrikon.csv", encoding="cp932")#文字コードのエラーが出るので encoding = "cp932"を指定。
df.head()
| 区市町村 | 平成14年の婚姻件数 | 平成15年の婚姻件数 | 平成16年の婚姻件数 | 平成17年の婚姻件数 | 平成18年の婚姻件数 | 平成19年の婚姻件数 | 平成20年の婚姻件数 | 平成21年の婚姻件数 | 平成22年の婚姻件数 | ... | 平成25年の離婚件数 | 平成26年の離婚件数 | 平成27年の離婚件数 | 平成28年の離婚件数 | 平成29年の離婚件数 | 平成30年の離婚件数 | 令和元年の離婚件数 | 令和2年の離婚件数 | 令和3年の離婚件数 | 令和4年の離婚件数 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 総数 | 84623 | 84755 | 84618 | 85382 | 89413.0 | 89243.0 | 91196.0 | 91028.0 | 91197.0 | ... | 24855 | 23653 | 24135 | 23470 | 23055 | 22706 | 22707 | 20783 | 19605 | 19255 |
| 1 | 区部 | 60265 | 60358 | 60812 | 61898 | 65569.0 | 65689.0 | 67418.0 | 67607.0 | 68036.0 | ... | 17867 | 16918 | 17436 | 16892 | 16399 | 16279 | 16310 | 14873 | 13828 | 13718 |
| 2 | 市部 | 23933 | 23958 | 23419 | 23107 | 23444.0 | 23159.0 | 23400.0 | 23049.0 | 22773.0 | ... | 6804 | 6593 | 6551 | 6423 | 6501 | 6301 | 6263 | 5764 | 5653 | 5396 |
| 3 | 郡部 | 274 | 281 | 248 | 247 | 254.0 | 273.0 | 245.0 | 242.0 | 262.0 | ... | 125 | 81 | 96 | 88 | 110 | 82 | 96 | 88 | 93 | 94 |
| 4 | 島部 | 151 | 158 | 139 | 130 | 146.0 | 122.0 | 133.0 | 130.0 | 126.0 | ... | 59 | 61 | 52 | 67 | 45 | 44 | 38 | 58 | 31 | 47 |
5 rows × 43 columns
列名が元号かつ婚姻・離婚両方はいっているので、まず西暦にし、婚姻・離婚は変数名に残す。
df.columns = ["区市町村"] + [str(year)+':婚姻' for year in range(2002,2023)] + [str(year)+':離婚' for year in range(2002,2023)]#列変数名を変更
df
| 区市町村 | 2002:婚姻 | 2003:婚姻 | 2004:婚姻 | 2005:婚姻 | 2006:婚姻 | 2007:婚姻 | 2008:婚姻 | 2009:婚姻 | 2010:婚姻 | ... | 2013:離婚 | 2014:離婚 | 2015:離婚 | 2016:離婚 | 2017:離婚 | 2018:離婚 | 2019:離婚 | 2020:離婚 | 2021:離婚 | 2022:離婚 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 総数 | 84623 | 84755 | 84618 | 85382 | 89413.0 | 89243.0 | 91196.0 | 91028.0 | 91197.0 | ... | 24855 | 23653 | 24135 | 23470 | 23055 | 22706 | 22707 | 20783 | 19605 | 19255 |
| 1 | 区部 | 60265 | 60358 | 60812 | 61898 | 65569.0 | 65689.0 | 67418.0 | 67607.0 | 68036.0 | ... | 17867 | 16918 | 17436 | 16892 | 16399 | 16279 | 16310 | 14873 | 13828 | 13718 |
| 2 | 市部 | 23933 | 23958 | 23419 | 23107 | 23444.0 | 23159.0 | 23400.0 | 23049.0 | 22773.0 | ... | 6804 | 6593 | 6551 | 6423 | 6501 | 6301 | 6263 | 5764 | 5653 | 5396 |
| 3 | 郡部 | 274 | 281 | 248 | 247 | 254.0 | 273.0 | 245.0 | 242.0 | 262.0 | ... | 125 | 81 | 96 | 88 | 110 | 82 | 96 | 88 | 93 | 94 |
| 4 | 島部 | 151 | 158 | 139 | 130 | 146.0 | 122.0 | 133.0 | 130.0 | 126.0 | ... | 59 | 61 | 52 | 67 | 45 | 44 | 38 | 58 | 31 | 47 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 63 | 御蔵島村 | 1 | 1 | 1 | 1 | 1.0 | 4.0 | 3.0 | 4.0 | 2.0 | ... | - | 4 | - | - | - | - | - | - | - | - |
| 64 | 八丈町 | 48 | 44 | 52 | 46 | 37.0 | 35.0 | 41.0 | 34.0 | 25.0 | ... | 18 | 17 | 20 | 18 | 14 | 16 | 15 | 21 | 10 | 12 |
| 65 | 青ケ島村 | 1 | - | - | - | 1.0 | 1.0 | 2.0 | 2.0 | 1.0 | ... | 1 | - | - | - | - | - | 1 | - | - | - |
| 66 | 小笠原村 | 25 | 23 | 25 | 15 | 27.0 | 17.0 | 21.0 | 16.0 | 17.0 | ... | 7 | 6 | 5 | 9 | 5 | 6 | 3 | 5 | 7 | 10 |
| 67 | 注 届出時の夫の住所により分類した。 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
68 rows × 43 columns
-冒頭の総数などと最終行の注意書きを削除
df = df[5:-1]
df
| 区市町村 | 2002:婚姻 | 2003:婚姻 | 2004:婚姻 | 2005:婚姻 | 2006:婚姻 | 2007:婚姻 | 2008:婚姻 | 2009:婚姻 | 2010:婚姻 | ... | 2013:離婚 | 2014:離婚 | 2015:離婚 | 2016:離婚 | 2017:離婚 | 2018:離婚 | 2019:離婚 | 2020:離婚 | 2021:離婚 | 2022:離婚 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5 | 千代田区 | 235 | 266 | 294 | 344 | 398.0 | 422.0 | 464.0 | 458.0 | 465.0 | ... | 88 | 94 | 117 | 125 | 119 | 121 | 134 | 131 | 109 | 115 |
| 6 | 中央区 | 729 | 761 | 949 | 1114 | 1292.0 | 1277.0 | 1403.0 | 1411.0 | 1522.0 | ... | 323 | 314 | 320 | 325 | 379 | 382 | 377 | 338 | 329 | 334 |
| 7 | 港区 | 1425 | 1533 | 1576 | 1724 | 1929.0 | 2094.0 | 2110.0 | 2172.0 | 2264.0 | ... | 585 | 546 | 651 | 613 | 573 | 595 | 559 | 510 | 491 | 503 |
| 8 | 新宿区 | 2159 | 2207 | 2284 | 2382 | 2459.0 | 2473.0 | 2642.0 | 2679.0 | 2735.0 | ... | 675 | 629 | 590 | 596 | 579 | 581 | 572 | 557 | 484 | 499 |
| 9 | 文京区 | 1252 | 1273 | 1319 | 1395 | 1583.0 | 1505.0 | 1579.0 | 1581.0 | 1648.0 | ... | 319 | 303 | 320 | 315 | 295 | 291 | 308 | 276 | 283 | 272 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 62 | 三宅村 | 12 | 8 | 10 | 14 | 13.0 | 17.0 | 16.0 | 21.0 | 17.0 | ... | 9 | 9 | 8 | 6 | 3 | 1 | 3 | 3 | 1 | 5 |
| 63 | 御蔵島村 | 1 | 1 | 1 | 1 | 1.0 | 4.0 | 3.0 | 4.0 | 2.0 | ... | - | 4 | - | - | - | - | - | - | - | - |
| 64 | 八丈町 | 48 | 44 | 52 | 46 | 37.0 | 35.0 | 41.0 | 34.0 | 25.0 | ... | 18 | 17 | 20 | 18 | 14 | 16 | 15 | 21 | 10 | 12 |
| 65 | 青ケ島村 | 1 | - | - | - | 1.0 | 1.0 | 2.0 | 2.0 | 1.0 | ... | 1 | - | - | - | - | - | 1 | - | - | - |
| 66 | 小笠原村 | 25 | 23 | 25 | 15 | 27.0 | 17.0 | 21.0 | 16.0 | 17.0 | ... | 7 | 6 | 5 | 9 | 5 | 6 | 3 | 5 | 7 | 10 |
62 rows × 43 columns
“年”を変数とした縦持ちデータに変換
melted_df = df.melt(id_vars = "区市町村", var_name = "年", value_name = "件数")
melted_df
| 区市町村 | 年 | 件数 | |
|---|---|---|---|
| 0 | 千代田区 | 2002:婚姻 | 235 |
| 1 | 中央区 | 2002:婚姻 | 729 |
| 2 | 港区 | 2002:婚姻 | 1425 |
| 3 | 新宿区 | 2002:婚姻 | 2159 |
| 4 | 文京区 | 2002:婚姻 | 1252 |
| ... | ... | ... | ... |
| 2599 | 三宅村 | 2022:離婚 | 5 |
| 2600 | 御蔵島村 | 2022:離婚 | - |
| 2601 | 八丈町 | 2022:離婚 | 12 |
| 2602 | 青ケ島村 | 2022:離婚 | - |
| 2603 | 小笠原村 | 2022:離婚 | 10 |
2604 rows × 3 columns
“年”変数から婚姻、離婚の値を取り出して新しく変数を作成する。
“年”変数自体もintに変換
melted_df['婚姻・離婚'] = melted_df['年'].str.split(':').apply(lambda x: x[1])
melted_df['年'] = melted_df['年'].str.split(':').apply(lambda x: x[0]).astype('int')
melted_df.head()
| 区市町村 | 年 | 件数 | 婚姻・離婚 | |
|---|---|---|---|---|
| 0 | 千代田区 | 2002 | 235 | 婚姻 |
| 1 | 中央区 | 2002 | 729 | 婚姻 |
| 2 | 港区 | 2002 | 1425 | 婚姻 |
| 3 | 新宿区 | 2002 | 2159 | 婚姻 |
| 4 | 文京区 | 2002 | 1252 | 婚姻 |
fig = px.line(melted_df, x = '年', y = '件数', color = '区市町村', line_dash = '婚姻・離婚',markers=True)#line_dashで婚姻と離婚を区別
fig
#fig.update_yaxes(row=1, col=2, showticklabels=True) # set the y-axis range and ticklabels for the second subplot
px.line(melted_df.query('区市町村.str.contains("区")', engine = 'python'), x = '年', y = '件数', color = '区市町村', line_dash = '婚姻・離婚',markers=True)#区のみ取り出す
問題#
上のコードを参考に東京都の合計特殊出生率の時系列推移([https://www.hokeniryo.metro.tokyo.lg.jp/kiban/chosa_tokei/jinkodotaitokei/kushityosonbetsu.files/04goukei.csv])をプロットしてください。
| 区市町村 | 平成5年 | 平成6年 | 平成7年 | 平成8年 | 平成9年 | 平成10年 | 平成11年 | 平成12年 | 平成13年 | ... | 平成25年 | 平成26年 | 平成27年 | 平成28年 | 平成29年 | 平成30年 | 令和元年 | 令和2年 | 令和3年 | 令和4年 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 総数 | 1.1 | 1.14 | 1.11 | 1.07 | 1.05 | 1.05 | 1.03 | 1.07 | 1 | ... | 1.13 | 1.15 | 1.24 | 1.24 | 1.21 | 1.2 | 1.15 | 1.12 | 1.08 | 1.04 |
| 1 | 区部 | 1.06 | 1.09 | 1.02 | 1.03 | 1.01 | 1 | 0.98 | 1 | 0.97 | ... | 1.16 | 1.19 | 1.22 | 1.22 | 1.2 | 1.19 | 1.13 | 1.12 | 1.09 | 1.04 |
| 2 | 市部 | 1.27 | 1.31 | 1.23 | 1.22 | 1.2 | 1.19 | 1.16 | 1.18 | 1.14 | ... | 1.27 | 1.28 | 1.32 | 1.31 | 1.28 | 1.27 | 1.23 | 1.18 | 1.15 | 1.12 |
| 3 | 郡部 | 1.33 | 1.32 | 1.39 | 1.34 | 1.21 | 1.32 | 1.04 | 1.23 | 1.14 | ... | 1.34 | 1.34 | 1.28 | 1.45 | 1.28 | 1.32 | 1.18 | 1.1 | 1.15 | 1.03 |
| 4 | 島部 | 2.12 | 1.75 | 1.78 | 1.67 | 1.7 | 1.67 | 1.78 | 1.74 | 1.52 | ... | 1.76 | 1.61 | 1.8 | 1.69 | 1.46 | 1.63 | 1.68 | 1.66 | 1.45 | 1.26 |
5 rows × 31 columns
問題#
国勢調査の時系列データ[https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031523105&fileKind=1]を使って全年齢に関する人口の時系列推移をプロットしてください。
| 都道府県コード | 都道府県名 | 年齢5歳階級 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 01 | 北海道 | 総数 | 大正 | 9.0 | 1920.0 | 2359183.0 | 1244322.0 | 1114861.0 |
| 1 | 01 | 北海道 | 0~4歳 | 大正 | 9.0 | 1920.0 | 376676.0 | 190044.0 | 186632.0 |
| 2 | 01 | 北海道 | 5~9歳 | 大正 | 9.0 | 1920.0 | 319370.0 | 161814.0 | 157556.0 |
| 3 | 01 | 北海道 | 10~14歳 | 大正 | 9.0 | 1920.0 | 270012.0 | 138018.0 | 131994.0 |
| 4 | 01 | 北海道 | 15~19歳 | 大正 | 9.0 | 1920.0 | 239092.0 | 125670.0 | 113422.0 |